package cn.ly.rabbit.controller;


import cn.ly.rabbit.config.RabbitConfig;
import cn.ly.rabbit.model.Order;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


/**
 * 模拟  【延时支付】
 * 业务场景：下订单后，30分钟内如果没有支付，订单将会自动失效
 * 实现原理：将消息设置过期属性，然后直接发到死信交换器中
 */
@RestController
@RequestMapping("/order")
public class DelayOrderController {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 【死信交换器的使用，情况二：】
     * 发送到：Direct死信交换器上（其实就一普通交换器），路由键为：myOrder.queue       //即要发送到的队列名字，Direct交换器嘛，懒得再起绑定建了
     * 虽然会发送到 【Order_Queue_Name】队列上，但是我在消费端，并没有设置监听 该队列的监听器【即没人消费】
     * 所以，这个消息会在队列中【过期】： 因为我在下面设置了消息过期时间
     * 且【Order_Queue_Name】该队列，我在消费端绑定了死信路由器，和死信路由键。当其成为死信时，将转发到死信队列
     * 故：过期后自动发送到死信路由器了。从而实现了延时订单功能
     */
    @GetMapping("/send4")
    public String send4(String msg, String routeKey) {
        if (routeKey == null || routeKey.equals("")) {
            routeKey = "test.b.123";
        }
        msg += "订单状态：0";
        System.out.println(RabbitConfig.DLX_Delay_Exchange_Name + ">>>>>>>>>>begin to send TOPIC:" + msg);

        //延时订单
        //投递消息到队列后，消息过期（即我们没有设置监听器去消费），然后被转发到死信路由器
        rabbitTemplate.convertAndSend(RabbitConfig.DLX_Delay_Exchange_Name, RabbitConfig.Order_Queue_Name, msg, processor -> {
            // 如果配置了 params.put("x-message-ttl", 5 * 1000); 那么这一句也可以省略,具体根据业务需要是声明 Queue 的时候就指定好延迟时间还是在发送自己控制时间
            processor.getMessageProperties().setExpiration(1000 * 8 + "");   //8s过期时间
            return processor;
        });
        return RabbitConfig.DLX_Delay_Exchange_Name + " will send:" + msg;

    }


}
